﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

using My_TV_Manager.Model;

namespace My_TV_Manager.View.ContentPanel.Track
{
    [System.ComponentModel.DesignerCategory("")]

    public class TrackSearchPanel : Panel
    {
        #region Private Data

        private Controller controller;

        private string previousSearch;

        private Panel searchPanel;
        private TextBox searchText;
        private Button searchButton;
        private SeriesCategoryPanel categoryPanel;
        List<SearchResult> searchData;
        List<SearchResultPanel> searchResultPanels;
        private Panel resultDisplayPanel;

        private BackgroundWorker searchWorker;

        #endregion

        #region Constructors

        // Base constructor
        public TrackSearchPanel(Size size, Color color, Controller controller)
        {
            this.Size = size;
            this.BackColor = color;
            this.controller = controller;
            controller.TrackSearchPanel = this;

            previousSearch = "";

            searchWorker = new BackgroundWorker();
            searchWorker.DoWork += new DoWorkEventHandler(searchWorker_DoWork);
            searchWorker.ProgressChanged += new ProgressChangedEventHandler(searchWorker_ProgressChanged);
            searchWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(searchWorker_RunWorkerCompleted);
            searchWorker.WorkerReportsProgress = true;
            searchWorker.WorkerSupportsCancellation = true;

            searchData = new List<SearchResult>();
            searchResultPanels = new List<SearchResultPanel>();

            searchPanel = new Panel();
            searchPanel.BackColor = Color.Transparent;
            searchPanel.ClientSize = new Size(this.ClientSize.Width, 51);
            searchPanel.Dock = DockStyle.Top;

            searchText = new TextBox();
            searchText.Text = "Series Name";
            searchText.Size = new Size(400, 31);
            searchText.Top = 10;
            searchText.BackColor = Color.White;
            searchText.Margin = new Padding(0);
            searchText.BorderStyle = BorderStyle.FixedSingle;
            searchText.Font = new Font("Helvetica", 16.0f, FontStyle.Regular);
            searchText.KeyPress += new KeyPressEventHandler(enterKeyPressHandler);

            searchButton = new Button();
            searchButton.Text = "Search";
            searchButton.Size = new Size(100, 30);
            searchButton.Top = 11;
            searchButton.BackColor = Color.White;
            searchButton.FlatStyle = FlatStyle.Flat;
            searchButton.FlatAppearance.BorderSize = 0;
            searchButton.Font = new Font("Helvetica", 16.0f, FontStyle.Regular);
            searchButton.Click += new EventHandler(searchEventHandler);

            int componentWidth = searchText.Width + 10 + searchButton.Width;
            searchText.Left = (this.Width - componentWidth) / 2;
            searchButton.Left = searchText.Left + searchText.Width + 10;

            searchPanel.Controls.Add(searchText);
            searchPanel.Controls.Add(searchButton);

            categoryPanel = new SeriesCategoryPanel(new Size(this.ClientSize.Width - 40, 30));
            categoryPanel.Location = new Point(controller.SearchResultDisplayPadding, 
                                               searchPanel.ClientSize.Height);

            resultDisplayPanel = new Panel();
            resultDisplayPanel.Location = new Point(controller.SearchResultDisplayPadding, 
                                                    categoryPanel.Location.Y + 
                                                    categoryPanel.ClientSize.Height + 
                                                    controller.SearchResultDisplayOffset);
            resultDisplayPanel.Size = new Size(this.ClientSize.Width -
                                               resultDisplayPanel.Location.X - 
                                               controller.SearchResultDisplayPadding,
                                               this.ClientSize.Height -
                                               resultDisplayPanel.Location.Y - 
                                               controller.SearchResultDisplayPadding);
            resultDisplayPanel.BackColor = Color.Transparent;
            resultDisplayPanel.AutoScroll = true;

            this.Controls.Add(searchPanel);
            this.Controls.Add(categoryPanel);
            this.Controls.Add(resultDisplayPanel);

            BuildSearchResultDisplayPanel();
        }

        #endregion

        #region Event Handlers

        private void searchEventHandler(object sender, EventArgs e)
        {
            searchButton.Focus();

            // Don't search if our previous search was the same
            if (searchText.Text == previousSearch) { return; }

            if (searchWorker.IsBusy)
            {
                searchWorker.CancelAsync();
            }
            else
            {
                previousSearch = searchText.Text;
                searchWorker.RunWorkerAsync();
            }
        }

        private void enterKeyPressHandler(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (Char)Keys.Enter)
            {
                e.Handled = true;
                searchButton.PerformClick();
            }
        }

        #endregion

        #region Search Background Worker Members

        public void searchWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            List<int> results = TVDB.GetSearchSeriesIDs(searchText.Text, controller);
            if (results == null) 
            {
                Console.Out.WriteLine("No internet connection: cannot search");
                return;
            }

            for (int i = 0; i < results.Count; i++)
            {
                if (searchWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                if (TVDB.GetSearchResultInfo(results[i], i, controller))
                {
                    searchWorker.ReportProgress(1);
                }
            }
        }

        public void searchWorker_ProgressChanged(object sender,
            ProgressChangedEventArgs e)
        {
            BuildSearchResultDisplayPanel();
        }

        public void searchWorker_RunWorkerCompleted(object sender,
            RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                searchButton.PerformClick();
            }
        }

        #endregion

        #region Functions

        public void AddTrackedSeries(SearchResult series)
        {
            foreach (SearchResultPanel result in searchResultPanels)
            {
                if (result.SearchResult.SeriesName == series.SeriesName)
                {
                    result.UpdatePanel();
                }
            }
        }

        public void RemoveTrackedSeries(SearchResult series)
        {
            foreach (SearchResultPanel result in searchResultPanels)
            {
                if (result.SearchResult.SeriesName == series.SeriesName)
                {
                    result.UpdatePanel();
                }
            }
        }

        public void BuildSearchResultDisplayPanel()
        {
            searchResultPanels.Clear();
            resultDisplayPanel.Controls.Clear();

            foreach (SearchResult result in controller.CurrentSearchResults)
            {
                SearchResultPanel panel = new SearchResultPanel(result,
                                                                controller.SearchResultBannerDisplayRatio,
                                                                new Size(resultDisplayPanel.Width - 20,
                                                                         controller.SearchResultDisplayHeight),
                                                                controller);
                panel.Top = searchResultPanels.Count * 
                            (controller.SearchResultDisplayHeight + 
                             controller.SearchResultDisplayOffset);
                panel.BackColor = controller.SearchResultPassiveColor;

                searchResultPanels.Add(panel);
                resultDisplayPanel.Controls.Add(searchResultPanels[searchResultPanels.Count - 1]);
            }
        }

        #endregion
    }
}
